#include "FMPlugin.h"

#include <QtCore>
#include <QtGui/QCompleter>
#include <QtGui/QHeaderView>
#include <QtGui/QInputDialog>
#include <QtGui/QLineEdit>
#include <QtGui/QMessageBox>
#include <QtGui/QMenu>
#include <QtGui/QPushButton>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>

#include <juffed/Log.h>
#include <juffed/MainSettings.h>
#include <juffed/PluginSettings.h>
#include <juffed/TextDocSettings.h>

#include "ManageDlg.h"
#include "TreeView.h"

FMPlugin::FMPlugin() : QObject(), JuffPlugin() {
	model_.setSorting(QDir::DirsFirst);

	w_ = new QWidget();
	w_->setWindowTitle(tr("Files"));

	tree_ = new TreeView(this);
	tree_->setModel(&model_);
	tree_->setDragDropMode(QAbstractItemView::DragOnly);
	tree_->setRootIsDecorated(false);
	tree_->setItemsExpandable(false);
	tree_->setAllColumnsShowFocus(true);
	tree_->header()->resizeSection(0, 180);
	tree_->header()->resizeSection(1, 80);
	tree_->header()->resizeSection(2, 60);
	tree_->header()->resizeSection(3, 180);
	tree_->initMenu();
	
	pathEd_ = new QLineEdit("");
	backBtn_ = new QPushButton(QIcon(":icon_back"), "");
	upBtn_ = new QPushButton(QIcon(":icon_up"), "");
	homeBtn_ = new QPushButton(QIcon(":icon_home"), "");
	currentBtn_ = new QPushButton(QIcon(":icon_current"), "");
	refreshBtn_ = new QPushButton(QIcon(":icon_refresh"), "");
	favoritesBtn_ = new QPushButton(QIcon(":icon_bookmarks"), "");
	newDirBtn_ = new QPushButton(QIcon(":icon_new_dir"), "");
	backBtn_->setToolTip(tr("Go back"));
	upBtn_->setToolTip(tr("Go to parent directory"));
	homeBtn_->setToolTip(tr("Go to home directory"));
	currentBtn_->setToolTip(tr("Go to current file's directory"));
	refreshBtn_->setToolTip(tr("Refresh"));
	favoritesBtn_->setToolTip(tr("Favorites"));
	newDirBtn_->setToolTip(tr("Create a new directory"));
	
	const int maxSize = 26;
	QPushButton* btns[] = { backBtn_, upBtn_, homeBtn_, refreshBtn_, 
		                    favoritesBtn_, newDirBtn_, currentBtn_, 0 };
	int i = 0;
	while ( QPushButton* btn = btns[i++] ) {
		btn->setMaximumWidth(maxSize);
		btn->setMaximumHeight(maxSize);
	}
	pathEd_->setCompleter(new QCompleter(&model_));

	QHBoxLayout* hBox = new QHBoxLayout();
	QVBoxLayout* vBox = new QVBoxLayout();
	hBox->setMargin(0);
	vBox->setMargin(0);
	hBox->setSpacing(2);
	vBox->setSpacing(2);

	hBox->addWidget(backBtn_);
	hBox->addWidget(upBtn_);
	hBox->addWidget(homeBtn_);
	hBox->addWidget(currentBtn_);
	hBox->addWidget(refreshBtn_);
	hBox->addWidget(favoritesBtn_);
	hBox->addWidget(newDirBtn_);
	hBox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
	vBox->addLayout(hBox);
	vBox->addWidget(pathEd_);
	vBox->addWidget(tree_);

	w_->setLayout(vBox);

	connect(tree_, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(itemDoubleClicked(const QModelIndex&)));
	connect(tree_, SIGNAL(goUp()), SLOT(up()));
	connect(backBtn_, SIGNAL(clicked()), SLOT(back()));
	connect(upBtn_, SIGNAL(clicked()), SLOT(up()));
	connect(homeBtn_, SIGNAL(clicked()), SLOT(home()));
	connect(currentBtn_, SIGNAL(clicked()), SLOT(currentDir()));
	connect(favoritesBtn_, SIGNAL(clicked()), SLOT(favorites()));
	connect(newDirBtn_, SIGNAL(clicked()), SLOT(newDir()));
	connect(refreshBtn_, SIGNAL(clicked()), &model_, SLOT(refresh()));
	connect(pathEd_, SIGNAL(returnPressed()), SLOT(textEntered()));

	QString favStr = PluginSettings::getStringValue(this, "favorites");
	if ( !favStr.isEmpty() )
		favorites_ = favStr.split(";");
	favoritesMenu_ = new QMenu(w_);
	addToFavoritesAct_ = new QAction(tr("Add current path"), this);
	manageFavoritesAct_ = new QAction(tr("Manage favorites"), this);
	connect(addToFavoritesAct_, SIGNAL(triggered()), this, SLOT(addToFavorites()));
	connect(manageFavoritesAct_, SIGNAL(triggered()), this, SLOT(manageFavorites()));
	initFavoritesMenu();

	QString lastDir = PluginSettings::getStringValue(this, "lastDir");
	if ( lastDir.isEmpty() )
		lastDir = QDir::homePath();
	cd(lastDir, false);
	backBtn_->setEnabled(false);
	
	applySettings();
}

FMPlugin::~FMPlugin() {
	delete w_;
}

QString FMPlugin::name() const {
	return "File manager";
}

QString FMPlugin::targetEngine() const {
	return "all";
}

QString FMPlugin::description() const {
	return "Simple file manager that lets to open files without a dialog";
}

QWidgetList FMPlugin::dockList() const {
	QWidgetList wList;
	wList << w_;
	return wList;
}

void FMPlugin::initFavoritesMenu() {
	favoritesMenu_->clear();

	favoritesMenu_->addAction(addToFavoritesAct_);
	favoritesMenu_->addAction(manageFavoritesAct_);
	if ( !favorites_.isEmpty() )
		favoritesMenu_->addSeparator();
	foreach (QString item, favorites_) {
		favoritesMenu_->addAction(item, this, SLOT(goToFavorite()));
	}
}


void FMPlugin::cd(const QString& path, bool addToHistory /*= true*/) {
	if ( QFileInfo(path).isDir() ) {
		if ( addToHistory ) {
			QString curPath = model_.filePath(tree_->rootIndex());
			history_.push(curPath);
			if ( !backBtn_->isEnabled() )
				backBtn_->setEnabled(true);
		}
		tree_->setRootIndex(model_.index(path));
		pathEd_->setText(path);
		pathEd_->setToolTip(path);
		PluginSettings::setStringValue(this, "lastDir", path);
	}
}

void FMPlugin::itemDoubleClicked(const QModelIndex& index) {
	QString path = model_.filePath(index);
	if ( QFileInfo(path).isDir() ) {
		cd(path);
	}
	else {
		manager()->openDoc(path);
	}
}

void FMPlugin::back() {
	if ( !history_.isEmpty() ) {
		QString dir = history_.pop();
		if ( history_.isEmpty() )
			backBtn_->setEnabled(false);
		cd(dir, false);
	}
}

void FMPlugin::up() {
	QModelIndex cur = tree_->rootIndex();
	QModelIndex parent = cur.parent();
	if ( parent.isValid() ) {
		cd(model_.filePath(parent));
		tree_->setCurrentIndex(cur);
	}
}

void FMPlugin::home() {
	cd(QDir::homePath());
}

void FMPlugin::currentDir() {
	QString curDocName;
	manager()->getCurDocName(curDocName);
	if ( !curDocName.isEmpty() ) {
		cd(QFileInfo(curDocName).absolutePath());
	}
}

void FMPlugin::favorites() {
	favoritesMenu_->exec(QCursor::pos());
}

void FMPlugin::newDir() {
	QString newDirName = QInputDialog::getText(tree_, tr("New directory"), tr("Directory name"));
	if ( !newDirName.isEmpty() ) {
		QDir curDir(model_.filePath(tree_->rootIndex()));
		if ( !curDir.mkdir(newDirName) ) {
			QMessageBox::warning(tree_, tr("Warning"), 
								 tr("Couldn't create a dir named '%1'").arg(newDirName));
		}
		else {
			model_.refresh(tree_->rootIndex());
		}
	}
}


void FMPlugin::goToFavorite() {
	QAction* a = qobject_cast<QAction*>(sender());
	if ( a ) {
		cd(a->text());
	}
}

void FMPlugin::addToFavorites() {
	QString path = model_.filePath(tree_->rootIndex());
	qDebug() << path;
	if ( !favorites_.contains(path) ) {
		favorites_.append(path);
		initFavoritesMenu();
		PluginSettings::setStringValue(this, "favorites", favorites_.join(";"));
	}
}

void FMPlugin::manageFavorites() {
	ManageDlg dlg(tree_, this);
	dlg.exec();
	QString favStr = PluginSettings::getStringValue(this, "favorites");
	if ( !favStr.isEmpty() )
		favorites_ = favStr.split(";");
	else
		favorites_ = QStringList();
	initFavoritesMenu();
}

void FMPlugin::textEntered() {
	if ( QFileInfo(pathEd_->text()).isDir() )
		cd(pathEd_->text());
	else
		pathEd_->setText(model_.filePath(tree_->rootIndex()));
}

void FMPlugin::onDocSaved(const QString& fileName) {
	QFileInfo fi(fileName);
	QModelIndex index = model_.index(fi.absolutePath());
	if ( index.isValid() ) {
		model_.refresh(index);
	}
}

void FMPlugin::applySettings() {
	QPalette plt = tree_->palette();
	plt.setColor(QPalette::Base, TextDocSettings::defaultBgColor());
	plt.setColor(QPalette::Text, TextDocSettings::defaultFontColor());

	QColor selBgColor = TextDocSettings::selectionBgColor();
	plt.setColor(QPalette::Highlight, selBgColor);
	if ( selBgColor.red() + selBgColor.green() + selBgColor.blue() < 3 * 255 / 2)
		plt.setColor(QPalette::HighlightedText, Qt::white);
	else
		plt.setColor(QPalette::HighlightedText, Qt::black);
	tree_->setPalette(plt);
	pathEd_->setPalette(plt);
}

Q_EXPORT_PLUGIN2(fm, FMPlugin)
